import React, { useState, useEffect, useRef, useReducer, useCallback } from 'react';
import { Spin } from 'antd';
import moment from 'moment';
import PropTypes from 'prop-types';

import { HttpCode } from '#/utils/contacts';
import { TRDefault, TRTooltip } from '@/components';
import { countNumber } from '@/utils';

import { getConfig, COLUMNS, UNITMAP, TOOLTIPCOLOR } from './helper';
import AsyncTable from './useTable';
import useCharts from './useCharts';
import styles from './index.less';

const ModuleCharts = ({
  queryAction,
  searchData: params,
  startDate,
  endDate,
  dateType,
  type,
  height,
  revenueAnalysis,
}) => {
  const __tooltip_ = useRef();

  const currentActiveMonth = moment(startDate).format('M'); //当前选中的月份
  const getCurrentMonth = new Date().getMonth() + 1; //当前月份

  const [pageConfig, setConfig] = useState({});

  const chartRef = useRef(null);

  let { Item } = useCharts(chartRef, pageConfig);

  const initialState = {
    loading: false,
    month: currentActiveMonth,
    tableBodyList: [],
    chartBodyList: [],
    dataSource: [],
    error: '', //error  empty
  };

  const reducer = (state, action) => {
    const { payload } = action;
    switch (action.type) {
      case 'TOGGLE_LOADING':
        return { ...state, loading: payload.loading };
      case 'SET_DATA_BODYLIST':
        return {
          ...state,
          ...payload,
          // tableBodyList: payload.tableBodyList,
          // chartBodyList: payload.chartBodyList,
        };
      case 'SET_TABLEBODYLIST': {
        return { ...state, dataSource: payload.dataSource };
      }
      case 'SET_MONTH':
        return {
          ...state,
          month: payload.month,
        };
      case 'SET_ERROR_PAGE':
        return {
          ...state,
          error: payload.error,
        };
      default:
        return state;
    }
  };
  const [state, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    const activeCurrentMonth = moment(endDate).format('M');
    let month = activeCurrentMonth > getCurrentMonth ? getCurrentMonth : activeCurrentMonth;
    const _month = activeCurrentMonth;
    dispatch({
      type: 'SET_MONTH',
      payload: { month: dateType === 'year' ? month : _month },
    });
  }, [startDate, type]);

  useEffect(() => {
    handleToopFormatter(state.month);
  }, [type, startDate, state.month, state.chartBodyList, Item]);

  const fetchDataWarp = useCallback(fetchData, [
    startDate,
    // endDate,
    // type,
    params.deptBodyList,
    queryAction,
    params.provinceIdList,
    params.selectType,
    params.selectIds,
  ]);
  async function fetchData() {
    dispatch({
      type: 'TOGGLE_LOADING',
      payload: { loading: true },
    });

    let res = await queryAction(params).catch(() => {
      dispatch({ type: 'TOGGLE_LOADING', payload: { loading: false } });
      dispatch({
        type: 'SET_ERROR_PAGE',
        payload: { error: 'error' },
      });
      return {};
    });

    if (res && res.statusCode === HttpCode.SUCCESS) {
      dispatch({
        type: 'TOGGLE_LOADING',
        payload: { loading: false },
      });
      if (type === 'ElectricitySales') {
        const { chartBodyList = [], tables = [], year } = res.saleTableBody;
        dispatch({
          type: 'SET_DATA_BODYLIST',
          payload: {
            chartBodyList,
            tableBodyList: tables,
            year,
          },
        });
      } else if (type === 'Transaction') {
        const { histogram, tables } = res;
        dispatch({
          type: 'SET_DATA_BODYLIST',
          payload: {
            chartBodyList: histogram.chartList,
            tableBodyList: tables,
          },
        });
      } else {
        const { chartBodyList = [], tableBodyList = [], year } = res.operateBody;
        dispatch({
          type: 'SET_DATA_BODYLIST',
          payload: {
            chartBodyList,
            tableBodyList,
            year,
          },
        });
      }
    }
  }

  useEffect(() => {
    fetchDataWarp();
  }, [fetchDataWarp]);

  const _onToopFormatter = (params) => {
    const firstItem = params[0].dataIndex;
    const month = firstItem + 1;

    dispatch({ type: 'SET_MONTH', payload: { month } });
    handleToopFormatter(month);
  };

  const handleToopFormatter = (month) => {
    let timer = `${state.year || moment(startDate).format('YYYY')}年${month}月`;
    let array = [];
    state.chartBodyList.map((item, index) => {
      const value =
        state.chartBodyList &&
        state.chartBodyList[index] &&
        state.chartBodyList[index].pointBodies[month - 1] &&
        state.chartBodyList[index].pointBodies[month - 1].value;

      const valueLabel = value || '-';

      array.push({
        name: item.name,
        val: value,
        value: valueLabel === '-' ? valueLabel : `${valueLabel}${UNITMAP[type][index]}`,
        color: TOOLTIPCOLOR[type][index],
      });
    });
    array.length &&
      type === 'Management' &&
      array.splice(array.length - 1, 0, {
        name: '毛利润计划偏差',
        value: array[1].val
          ? `${countNumber(Number(array[1].val), Number(array[0].val), '-')}万元`
          : '-',
      });
    __tooltip_.current && __tooltip_.current.show(timer, array);
  };

  useEffect(() => {
    getChartBodyList();
    !!state.tableBodyList && getDataSource();
    !!state.tableBodyList && getColumns();
  }, [state.chartBodyList, state.tableBodyList]);

  useEffect(() => {
    getColumns();
    getDataSource();
  }, [state.month]);

  const getDataSource = () => {
    let dataSource = [];
    if (type === 'Transaction' || type === 'ElectricitySales') {
      dataSource =
        state.tableBodyList[state.month - 1] &&
        state.tableBodyList[state.month - 1].tradingTable &&
        state.tableBodyList[state.month - 1].tradingTable.rowList;
    } else {
      dataSource =
        state.tableBodyList[state.month - 1] && state.tableBodyList[state.month - 1].children;
    }
    dispatch({
      type: 'SET_TABLEBODYLIST',
      payload: { dataSource },
    });
  };

  const getXYAxisIndex = (index, type) => {
    const axisConfig = {
      Management: [
        { xAxisIndex: 0, yAxisIndex: 0, barGap: '50%' },
        { xAxisIndex: 0, yAxisIndex: 0, barGap: '50%' },
        { xAxisIndex: 1, yAxisIndex: 1, barGap: '50%' },
        { xAxisIndex: 1, yAxisIndex: 1, barGap: '50%' },
      ],
      Transaction: [
        { xAxisIndex: 0, yAxisIndex: 0 },
        { xAxisIndex: 2, yAxisIndex: 0 },
        { xAxisIndex: 2, yAxisIndex: 2 },
        { xAxisIndex: 0, yAxisIndex: 2 },
      ],
      ElectricitySales: [
        { xAxisIndex: 0, yAxisIndex: 0 },
        { xAxisIndex: 2, yAxisIndex: 0 },
        { xAxisIndex: 2, yAxisIndex: 0 },
        { xAxisIndex: 0, yAxisIndex: 0 },
      ],
    };
    if (!axisConfig[type]) return {};
    return axisConfig[type][index] || {};
  };
  const getChartBodyList = () => {
    let series = [];

    state.chartBodyList &&
      state.chartBodyList.map((item, index) => {
        if (item.type === 'text') return;

        const isNegate = type === 'Management' && item.name.indexOf('成本') > -1;

        const axisIndex =
          item.type === 'bar'
            ? getXYAxisIndex(index, type)
            : item.type === 'line'
            ? {
                xAxisIndex: 1,
                yAxisIndex: 1,
                symbol: 'none',
                lineStyle: { width: 1 },
              }
            : {};

        const seriesData = item.pointBodies.map((point) => {
          return point.value ? (isNegate ? -point.value : point.value) : 0;
        });

        series.push({
          name: item.name,
          type: item.type,
          barGap: '80%',
          ...axisIndex,
          itemStyle: {
            normal: {
              color: item.color,
              barBorderRadius: isNegate ? [0, 0, 20, 20] : [20, 20, 0, 0],
            },
          },
          data: seriesData,
          barWidth: 8,
        });
      });

    let config = getConfig(type);
    if (revenueAnalysis) {
      config.legend.textStyle = { color: '#fff' };
    }

    const tooltip = {
      trigger: 'axis',
      extraCssText: 'box-shadow: 0 0 10px rgba(0, 0, 0, 0.1)',
      backgroundColor: 'rgba(255, 255, 255, 1)',
      textStyle: {
        color: '#888E95',
        borderWidth: 1,
        borderColor: '#1A253C4B',
        padding: 12,
      },
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: revenueAnalysis ? '#161A1D' : '#F5F8FA',
          color: revenueAnalysis ? '#D3D4D4' : '#888E95',
          shadowBlur: 0,
        },
      },
      formatter: (params) => {
        _onToopFormatter(params);
      },
    };
    const pageConfig = { ...config, tooltip, series };
    setConfig(pageConfig);
  };

  const getColumns = () => {
    const _columns = COLUMNS[type].map((item) => {
      return {
        ...item,
        title:
          item.type === ''
            ? item.title
            : item.type === 'month'
            ? `${state.month}${item.title}`
            : `${getMonth(state.month)}${item.title}`,
        width: item.width ? item.width : 80,
      };
    });
    return _columns;
  };

  const getMonth = (val) => {
    return val > 1 ? `1-${val}` : val;
  };

  if (state.error === 'error') return <TRDefault type="error" message="接口请求错误" />;
  return (
    <>
      {state.loading ? (
        <Spin
          style={{
            width: '100%',
            height: '300px',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
          }}
        />
      ) : (
        <div className={styles.chartsWrap}>
          <div style={{ width: '100%' }}>
            <TRTooltip ref={__tooltip_} suffixText="" />
            <div className={styles.charts} style={{ width: '100%', ...height }} ref={chartRef} />
            <div className={styles.lineBox} />
            <AsyncTable
              type={type}
              owncolumns={() => getColumns()}
              baseProps={{ rowKey: (record) => record.id || record.typeName }}
              loading={state.loading}
              dataSource={state.dataSource}
            />
          </div>
        </div>
      )}
    </>
  );
};

ModuleCharts.propTypes = {
  queryAction: PropTypes.func,
  searchData: PropTypes.object,
  dateType: PropTypes.string,
  startDate: PropTypes.string,
  endDate: PropTypes.string,
  type: PropTypes.string,
  height: PropTypes.object,
};
export default ModuleCharts;
